/*
 * Copyright 2009 Max Kugland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.splink.deepsplink.page.request {
	import org.splink.deepsplink.config.ConfigData;
	import org.splink.deepsplink.config.PageData;
	import org.splink.library.tree.INode;
	import org.splink.library.tree.Tree;

	/**
	 * Builds the appropritate <code>IRequestBuilder</code> for the current request.
	 * Computes the common parent page of the last requested page and the current
	 * requested page and returns the <code>IRequestBuilder</code> implementation which
	 * has been set for this page. Alternatively the default <code>IRequestBuilder</code> 
	 * implementation <code>HideInitializeAndShowFinalize</code> is returned.
	 * 
	 * @see org.splink.deepsplink.page.request.IRequestBuilder
	 * @author Max Kugland
	 */
	public class RequestBuilderFactory {
		private var _i_h_s_f : IRequestBuilder;		private var _is_h_f : IRequestBuilder;		private var _i_s_h_f : IRequestBuilder;
		private var _h_i_s_f : IRequestBuilder;
		private var _h_is_f : IRequestBuilder;
		private var _i_sh_f : IRequestBuilder;

		private var _tree : Tree;
		private var _config : ConfigData;

		/**
		 * @param config the deepsplink configuration
		 * @param tree deepsplinks underlying <code>Tree</code> which defined the page structure
		 * @param overlayIds an <code>Array</code> of Strings defining the pages to be handled as overlays
		 */
		public function RequestBuilderFactory(config : ConfigData, tree : Tree, overlayIds : Array) {
			_config = config;
			_tree = tree;
			
			_i_h_s_f = new InitializeHideShowFinalize(overlayIds);			_is_h_f = new InitializeAndShowHideFinalize(overlayIds);			_i_s_h_f = new InitializeShowHideFinalize(overlayIds);
			_h_i_s_f = new HideInitializeShowFinalize(overlayIds);
			_h_is_f = new HideInitializeAndShowFinalize(overlayIds);			_i_sh_f = new InitializeShowAndHideFinalize(overlayIds);		}

		/**
		 * Returns the required <code>IRequestBuilder</code> implementation. Information on 
		 * which implementation might be required is found within the common parent page of
		 * the current request and the page of the last page request.
		 * 
		 * @param id the id of the page which has been requested
		 * @return the required <code>IRequestBuilder</code> implementation
		 */
		public function create(id : String) : IRequestBuilder {
			var type : String = getFirstRequestBuilderType(Tree.getParentNodeChain(Tree.getNodeById(id, _tree.root)));
			
			switch(type) {
				case _i_h_s_f.type:
					return _i_h_s_f;
					
				case _is_h_f.type:
					return _is_h_f;
					
				case _i_s_h_f.type:
					return _i_s_h_f;
					
				case _h_i_s_f.type:
					return _h_i_s_f;
					
				case _i_sh_f.type:
					return _i_sh_f;
			}
			
			return _h_is_f;
		}

		private function getFirstRequestBuilderType(parentNodeChain : Array) : String {
			for each (var n : INode in parentNodeChain) {
				var type : String = getRequestBuilderTypeFromConfig(n.id, _config.pageData.pageDataArray);
				if(type) {
					return type;			
				}
			}
			return _config.pageData.request;
		}

		private function getRequestBuilderTypeFromConfig(id : String, pages : Array) : String {
			for each (var p : PageData in pages) {
				if(p.id == id && p.request) {
					return p.request;
				} else {
					var r : String = getRequestBuilderTypeFromConfig(id, p.pageDataArray);
					if(r) return r;
				}
			}
			return null;
		}
	}
}
